package com.demo.config;

import com.demo.common.JsonResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * 认证配置文件
 * '@EnableGlobalMethodSecurity' 注解请自行百度理解...
 *
 * @date 2021/4/30 16:26
 */
//@Configuration
//@EnableWebSecurity
//@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
@Deprecated
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 这里报红不影响,可以把实现的@service注解去掉就不会报红了
     **/
    @Autowired
    private UserDetailsService detailsService;

    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        //开启注解配置的Bean
        return super.authenticationManagerBean();
    }

    /**
     * 密钥认证器
     *
     * @date 2021/4/30
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(detailsService).passwordEncoder(new BCryptPasswordEncoder());
    }

    /**
     * 路径排除器
     *
     * @date 2021/4/30
     */
    @Override
    public void configure(WebSecurity web) {
        //排除不需要权限访问的接口
        web.ignoring().antMatchers("/404", "/static/**", "/user/loginErr", "/favicon.ico");
    }

    /**
     * 功能配置器
     *
     * @date 2021/4/30
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest()
                .authenticated();

        http
                .formLogin()
                //.usernameParameter("username") //默认username
                //.passwordParameter("password") //默认password
                .loginProcessingUrl("/user/login") //登入路径
                .loginPage("/user/loginErr") //没有登入,访问错误的路径
                .successHandler((request, response, authentication) -> {
                    response.setContentType("text/json;charset=UTF-8");
                    response.getWriter().write(new ObjectMapper().writeValueAsString(JsonResult.okMsg("登入成功!")));
                })
                .failureHandler((request, response, e) -> {
                    e.printStackTrace();
                    response.setContentType("text/json;charset=UTF-8");
                    response.getWriter().write(new ObjectMapper().writeValueAsString(JsonResult.fail("登入失败!")));
                });
        http.

                exceptionHandling().accessDeniedHandler((request, response, e) -> {
            e.printStackTrace();

            response.setContentType("text/json;charset=UTF-8");
            response.getWriter().write(new ObjectMapper().writeValueAsString(JsonResult.fail("权限缺少!")));
        });


        http
                .logout()
                .logoutUrl("/user/logout") //登出路径
                .logoutSuccessHandler((request, response, authentication) -> {
                    response.setContentType("text/json;charset=UTF-8");
                    response.getWriter().write(new ObjectMapper().writeValueAsString(JsonResult.okMsg("退出成功")));
                });


        http    //PC端只能一个用户在线,这个功能没有测试
                .sessionManagement()
                .maximumSessions(1)
                .sessionRegistry(new SessionRegistryImpl()).expiredUrl("/404");

        http    //开启跨域
                .csrf().disable();
    }
}
